package com.ztx.jpaTest;

import org.junit.Test;

import java.util.Date;

/**
 * JpaTestEntity
 *
 * EntityManager --- 各种方法
 *
 * @author: Jovi
 *
 * @createTime: 2018/8/3 下午3:00
 *
 **/
public class JpaTestEntity extends JpaTest {

    /*
     * 类似于hibernate Session的saveOrUpdate方法。
     */
    @Test
    public void testMerge1() {
        // 1.若传入的是一个临时对象，会创建一个新的对象，把临时对象的属性，复制到新的对象中，然后对新的对象进行insert持久化操作，所以
        // 新的对象中有id，但以前的临时对象中没有id
        Customer customer = new Customer();
        customer.setAge(10);
        customer.setBirth(new Date());
        customer.setCreateTime(new Date());
        customer.setEmail("123");
        customer.setLastName("BB");

        Customer customer2 = entityManager.merge(customer);

        System.out.println("customer#id:" + customer.getId());
        System.out.println("customer2#id:" + customer2.getId());
    }

    @Test
    public void testMerge2() {
        /**
         *  如果传入的是一个游离对象，即传入的对象有OID
         *  1.若在EntityManager 缓存中没有该对象
         *  2.若在数据库中也没有对应的记录
         *  3.JPA会创建一个新的对象，把当前游离对象的属性复制到新创建的对象中
         *  4.对新创建的对象执行insert操作
         */
        Customer customer = new Customer();
        customer.setAge(11);
        customer.setBirth(new Date());
        customer.setCreateTime(new Date());
        customer.setEmail("123");
        customer.setLastName("DD");
        customer.setId(100);
        Customer customer2 = entityManager.merge(customer);

        System.out.println("customer#id:" + customer.getId());
        System.out.println("customer2#id:" + customer2.getId());
    }

    @Test
    public void testMerge3() {
        // 如果传入的是一个游离对象，即传入的对象有OID
        // 1.若在EntityManager 缓存中没有该对象
        // 2.若在数据库中有对应的记录
        // 3.JPA会查询对应的记录，然后返回该记录对应的对象，再然后会把游离对象的属性复制到查询到的对象中
        // 4.对查询到的对象执行update操作
        Customer customer = new Customer();
        customer.setAge(11);
        customer.setBirth(new Date());
        customer.setCreateTime(new Date());
        customer.setEmail("123EEE");
        customer.setLastName("EEEE");
        customer.setId(4);
        Customer customer2 = entityManager.merge(customer);

        System.out.println(customer2 == customer);
    }

    @Test
    public void testMerge4() {
        // 如果传入的是一个游离对象，即传入的对象有OID
        // 1.若在EntityManager 缓存中有该对象
        // 3.JPA会把游离对象的属性复制到EntityManager缓存中的对象中
        // 4.EntityManager 缓存中的对象执行update
        Customer customer = new Customer();
        customer.setAge(11);
        customer.setBirth(new Date());
        customer.setCreateTime(new Date());
        customer.setEmail("123FF");
        customer.setLastName("VVVVVV");
        customer.setId(4);
        Customer customer2 = entityManager.find(Customer.class, 4);
        entityManager.merge(customer);

        System.out.println(customer2 == customer);
    }

    @Test
    /**
     * 类似hibernate中Session的get方法
     * */
    public void testFind() {
        // 这里在调用find方法的时候就会去数据库里查询，不管定义的这个customer用没用到
        Customer customer = entityManager.find(Customer.class, 1);
        // 这里会输出com.ztx.jpaTest.jpa_test1.Customer，是真的对象
        System.out.println(customer.getClass().getName());
        System.out.println("-------------------------------");
        System.out.println(customer);
    }

    @Test
    // 类似hibernate中Session的load方法
    public void testGetReference() {
        // 这里只是在需要用到的时候才会去数据库里执行查询语句，和find方法相反
        Customer customer = entityManager.getReference(Customer.class, 1);

        // 这里会输出com.ztx.jpaTest.jpa_test1.Customer_$$_jvstd87_0，是一个代理对象
        System.out.println(customer.getClass().getName());
        System.out.println("-------------------------------");

        // 这里如果在调用之前就关掉事务，就会报懒加载异常信息
        // transaction.commit();
        // entityManager.close();
        System.out.println(customer);
    }

    @Test
    // 类似hibernate的save方法，使对象由临时状态变为持久化状态
    // 和hibiernate的save方法不同之处，若对象有id,则不能执行inster操作，而会抛异常。
    public void testPersistence() {
        Customer customer = new Customer();
        customer.setAge(12);
        customer.setBirth(new Date());
        customer.setCreateTime(new Date());
        customer.setEmail("123");
        customer.setLastName("xiao");
        entityManager.persist(customer);
        System.out.println(customer.getId());
    }

    // 类似hibernate的Delete方法，把对象对应的记录从数据库中移除
    // 注意：该方法只能移除持久化对象，而hibernate的delete方法实际上还可以移除游离对象
    @Test
    public void testRemover() {
        // 这里不能移除游离对象，而hibernate中可以
        // Customer customer = new Customer();
        // customer.setId(1);

        Customer customer = entityManager.find(Customer.class, 1);
        entityManager.remove(customer);
    }



    /**
     * 同hibernate 中session的flush方法
     */
    @Test
    public void testFlush() {
        Customer customer = entityManager.find(Customer.class, 1);
        System.out.println(customer);

        customer.setLastName("Jovi");
        entityManager.flush();
    }

    @Test
    public void testRefresh() {

        Customer customer = entityManager.find(Customer.class, 1);
        entityManager.refresh(customer);//又执行一遍select方法

    }
}
